package top.meijhm.communitymanagement.user.api;

import io.swagger.annotations.*;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.http.HttpStatus;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.servlet.support.ServletUriComponentsBuilder;
import top.meijhm.communitymanagement.common.exceptions.ObjectConflictException;
import top.meijhm.communitymanagement.common.exceptions.ObjectNotFoundException;
import top.meijhm.communitymanagement.common.exceptions.ParamCheckFailedException;
import top.meijhm.communitymanagement.common.swagger.SwaggerConfig;
import top.meijhm.communitymanagement.user.model.User;
import top.meijhm.communitymanagement.user.service.UserService;

import javax.servlet.http.HttpServletResponse;
import java.net.URI;
import java.util.List;

@RestController
@RequestMapping("/user")
@CrossOrigin(origins = "*")
@Api(tags = {SwaggerConfig.USER_API})
@Slf4j
public class UserController {
    @Autowired
    private UserService userService;

    @GetMapping("/id/{id}")
    @ApiOperation(value = "根据用户id查询", notes = "可调用角色[ROLE_ADMIN, ROLE_USER]")
    @ApiResponses({
            @ApiResponse(code = 404, message = "未找到用户")
    })
    @PreAuthorize("hasAnyRole('ROLE_ADMIN', 'ROLE_USER')")
    public User getUserById(@ApiParam(value = "用户id", name = "id", required = true) @PathVariable("id") Long id,
                            @RequestHeader(value = "Authorization") String Authorization) {
        return userService.getUserById(id);
    }

    @GetMapping("/name/{username}")
    @ApiOperation(value = "根据用户名查询", notes = "可调用角色[ROLE_ADMIN, ROLE_USER]")
    @ApiResponses({
            @ApiResponse(code = 404, message = "未找到用户")
    })
    @PreAuthorize("hasAnyRole('ROLE_ADMIN', 'ROLE_USER')")
    public User getUserByName(@ApiParam(value = "用户名", name = "username", required = true) @PathVariable String username,
                              @RequestHeader(value = "Authorization") String Authorization) {
        return userService.getUserByName(username);
    }

    @GetMapping("/role/{role}")
    @ApiOperation(value = "根据用户角色查询所有用户", notes = "不分页")
    @ApiResponses({
            @ApiResponse(code = 404, message = "未找到用户")
    })
    @PreAuthorize("hasAnyRole('ROLE_ADMIN')")
    public List<User> getUserByRole(@ApiParam(value = "用户角色", name = "role", required = true) @PathVariable String role,
                                    @RequestHeader(value = "Authorization") String Authorization) throws ObjectNotFoundException {
        return userService.getUsersByRole(role);
    }

    @PreAuthorize("hasAnyRole('ROLE_ADMIN', 'ROLE_USER')")
    @GetMapping("")
    @ApiOperation(value = "查询所有用户", notes = "不分页")
    public List<User> getUsers(@RequestHeader(value = "Authorization") String Authorization) {
        return userService.getUsers();
    }

    @PreAuthorize("hasAnyRole('ROLE_ADMIN', 'ROLE_USER')")
    @GetMapping("/page")
    @ApiOperation(value = "查询所有用户", notes = "分页")
    public Page<User> getPageUsers(@ApiParam(value = "页码，起始页为0，默认0") @RequestParam(name = "page", required = false, defaultValue = "0") Integer page,
                                   @ApiParam(value = "页面大小，默认20") @RequestParam(name = "size", required = false, defaultValue = "20") Integer size,
                                   @RequestHeader(value = "Authorization") String Authorization) {
        return userService.getPageUsers(page, size);
    }

    @PostMapping("")
    @ApiOperation(value = "创建用户", code = 201, notes = "可调用角色[ROLE_ADMIN]",
            consumes = "application/json", produces = "application/json")
    @ApiResponses({
            @ApiResponse(code = 201, message = "创建成功", responseHeaders = {
                    @ResponseHeader(name = "location", response = String.class, description = "创建用户的链接")
            }),
            @ApiResponse(code = 409, message = "用户名冲突")
    })
    @PreAuthorize("hasAnyRole('ROLE_ADMIN')")
    public User addUser(@ApiParam(value = "用户，必填字段：username，password", name = "User", required = true)
                        @RequestBody User user, @RequestHeader(value = "Authorization") String Authorization, HttpServletResponse response) throws ObjectConflictException {
        log.debug("创建用户：{}", user);
        User res = userService.addUser(user);
        URI uri = ServletUriComponentsBuilder.fromCurrentRequest().path("/id/{id}").buildAndExpand(res.getId()).toUri();
        response.setHeader("location", uri.toString());
        response.setStatus(HttpStatus.CREATED.value());
        return res;
    }

    @DeleteMapping(value = "/drop/{username}")
    @PreAuthorize("hasAnyRole('ROLE_ADMIN')")
    @ApiOperation(
            value = "彻底删除指定的用户",
            notes = "可调用角色[ROLE_ADMIN]",
            consumes = "application/json",
            produces = "application/json"
    )
    @ApiResponses(value = {
            @ApiResponse(code = 404, message = "无删除对象")
    })
    public void dropByName(
            @ApiParam(value = "用户名") @PathVariable String username,
            @RequestHeader(value = "Authorization") String Authorization
    ) throws ObjectNotFoundException {
        log.debug("Dropping user [{}].", username);
        userService.dropUserByName(username);
    }

    @DeleteMapping(value = "/name/{username}")
    @PreAuthorize("hasAnyRole('ROLE_ADMIN')")
    @ApiOperation(
            value = "删除指定的用户",
            notes = "可调用角色[ROLE_ADMIN]",
            consumes = "application/json",
            produces = "application/json"
    )
    @ApiResponses(value = {
            @ApiResponse(code = 404, message = "无删除对象")
    })
    public void deleteByName(
            @ApiParam(value = "用户名") @PathVariable String username,
            @RequestHeader(value = "Authorization") String Authorization
    ) throws Exception {
        log.debug("Deleting user [{}].", username);
        userService.deleteUserByName(username);
    }

    @DeleteMapping(value = "/id/{id}")
    @PreAuthorize("hasAnyRole('ROLE_ADMIN')")
    @ApiOperation(
            value = "删除指定的用户",
            notes = "可调用角色[ROLE_ADMIN]",
            consumes = "application/json",
            produces = "application/json"
    )
    @ApiResponses(value = {
            @ApiResponse(code = 404, message = "无删除对象")
    })
    public void deleteById(
            @ApiParam(value = "用户id") @PathVariable Long id,
            @RequestHeader(value = "Authorization") String Authorization
    ) throws Exception {
        log.debug("Deleting user id: [{}].", id);
        userService.deleteUserById(id);
    }

    @PutMapping(value = "/{id}")
    @PreAuthorize("hasAnyRole('ROLE_ADMIN')")
    @ApiOperation(
            value = "更新指定的用户",
            notes = "可调用角色[ROLE_ADMIN]",
            consumes = "application/json",
            produces = "application/json"
    )
    @ApiResponses(value = {
            @ApiResponse(code = 404, message = "无更新对象")
    })
    public User update(
            @ApiParam(value = "用户UUID") @PathVariable("id") Long id,
            @ApiParam(value = "更新的字段，允许更新password, description, userRole", name = "User")
            @RequestBody User user,
            @RequestHeader(value = "Authorization") String Authorization) throws Exception {
        log.debug("Updating user id: [{}].", id);
        if (user.getId() != null && !id.equals(user.getId())) {
            throw new ParamCheckFailedException(String.format("User id [%s] is illegal.", user.getId()));
        }
        user.setId(id);
        return userService.updateUser(user);
    }
}